package statistics.poznavaniTextu;

import java.awt.*;
import java.util.ArrayList;

/*
*   File E2 
*   in package statistics.poznavaniTextu
*   was created by slaha
*   on 30.4.12 at 13:37.
*
*/
public class E2 {
  double sumX,sumY, sumxx, sumyy, sumXY;
  double xbar, ybar,  varx, vary, covarxy;
  double[] dx, dy;

  double sumdxdx = 0, sumdydy = 0, sumdxdy = 0;

  double theta;

  double[] X, Y;

  double sumXXX = 0,  sumYYY = 0, varXXX = 0, varYYY = 0;


  int n = 0; //..počet
  double pxX, pxY;

 public double osaA, osaB;

  
  public E2 (ArrayList<PointBasen> body, double pxX, double pxY) {
    this.pxX = 1;
    this.pxY = 1;

    sumX = sumY = sumxx = sumyy = sumXY = 0;

    for (PointBasen p : body) {
      sumX += p.x;
      sumY += p.y;
      sumxx += (p.x*p.x);
      sumyy += (p.y*p.y);
      sumXY += (p.x*p.y);
      n++;
    }

    this.xbar = sumX / n;
    this.ybar = sumY / n;
    this.varx = sumxx / n;
    this.vary = sumyy / n;
    this.covarxy = sumXY / n;

    dx = new double[n];
    dy = new double[n];

    int i = 0;
    for (PointBasen p : body) {
      dx[i] = (p.x - xbar);
      dy[i] = (p.y - ybar);
      i++;
    }

    for (i = 0; i < dx.length; i++) {
      sumdxdx += (dx[i] * dx[i]);
      sumdydy += (dy[i] * dy[i]);
      sumdxdy += (dx[i] * dy[i]);
    }

    theta = 0.5 * Math.atan(2 * sumdxdx / (sumdydy * sumdxdx));

    double c = Math.cos(theta);
    double s = Math.sin(theta);

    X = new double[dx.length];
    Y = new double[dy.length];

    for (i = 0; i < X.length; i++) {
      X[i] = ((c * dx[i]) - (s * dy[i]));
      Y[i] = ((s * dx[i]) - (c * dy[i]));
    }

    for (i = 0; i < X.length; i++) {
      sumXXX += (X[i] * X[i]);
      sumYYY += (Y[i] * Y[i]);
    }

    varXXX = sumXXX / n;
    varYYY = sumYYY / n;

    osaA = Math.sqrt(varXXX);
    osaB = Math.sqrt(varYYY);
  }

  public void paint(Graphics2D g) {
      drawEllipse((int) xbar, (int) ybar, osaA, osaB, g );

//    EllipseMidpoint((int) xbar, (int) ybar, osaA, osaB, g);
  }

  public void EllipseMidpoint(int xcenter, int ycenter, double Rx, double Ry, Graphics2D g) {
    g.rotate(theta);
    double Rx2 = Rx * Rx;
    double Ry2 = Ry * Ry;
    double two_Rx2 = 2 * Rx2;
    double two_Ry2 = 2 * Ry2;

    double x = 0;
    double y = Ry;
    double p;
    double px = 0;
    double py = two_Rx2 * y;

    EllipsePlotpoint(xcenter, ycenter, x, y,g);

    /*Region 1*/
    p = (Ry2 - (Rx2 * Ry) + (0.25 + Rx2));
    while (px < py) {
      x++;
      px += two_Ry2;
      if (p < 0) {
        p += Ry2 + px;
      } else {
        y--;
        py -= two_Rx2;
        p += Ry2 + px - py;
      }
      EllipsePlotpoint(xcenter, ycenter, x, y,g);
    }

    /* Region2 */
    p = (Ry2 * (x + 0.5) * (x + 0.5) + Rx2 * (y - 1) * (y - 1) - Rx2 * Ry2);
    while (y > 0) {
      y--;
      py -= two_Rx2;
      if (p > 0) {
        p += Rx2 - py;
      } else {
        x++;
        px += two_Ry2;
        p += Rx2 + px - py;
      }
      EllipsePlotpoint(xcenter, ycenter, x, y,g);
    }

    g.rotate(-theta);
  }

  public void EllipsePlotpoint(int xcenter, int ycenter, double xx, double yy, Graphics2D g) {
    double x = xx;
    double y = yy;
    setPixel(xcenter + x, ycenter + y, g);
    setPixel(xcenter - x, ycenter + y,g);
    setPixel(xcenter + x, ycenter - y,g);
    setPixel(xcenter - x, ycenter - y,g);

  }

  public void setPixel(double x, double y, Graphics2D g) {
    int xx = (int) Math.round(x * pxX);
    int yy = (int) Math.round(y * pxY);
    g.fillOval(xx, yy, 1, 1);
  }





//////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////


  void drawEllipse(int x0, int y0, double a, double b, Graphics2D g)  {
    if (a == 0 || b == 0)
      return;
    a = Math.abs(a);
    b = Math.abs(b);
    double a2=2 * a * a;
    double b2=2 * b * b;
    double error=a * a * b;
    double x=0;
    double y=b;
    double stopy=0;
    double stopx =a2 * b;
    while (stopy <= stopx) {
      mySetPixel(x0 + x, y0 + y, g);
      mySetPixel(x0 - x, y0 + y, g);
      mySetPixel(x0 - x, y0 - y, g);
      mySetPixel(x0 + x, y0 - y, g);
      x += 0.01;
      error -= b2 * (x - 1);
      stopy += b2;
      if (error <= 0) {
        error += a2 * (y - 1);
        --y;
        stopx -= a2;
      }
    }

    error = b * b * a;
    x = a;
    y = 0;
    stopy = b2 * a;
    stopx = 0;
    while (stopy >= stopx) {
      mySetPixel(x0 + x, y0 + y, g);
      mySetPixel(x0 - x, y0 + y, g);
      mySetPixel(x0 - x, y0 - y, g);
      mySetPixel(x0 + x, y0 - y, g);
      ++y;
      error -= a2 * (y - 1);
      stopx += a2;
      if (error < 0) {
        error += b2 * (x - 1);
        --x;
        stopy -= b2;
      }
    }
  }

  void mySetPixel(double x, double y, Graphics2D graphics)

  {

    graphics.drawRect((int) Math.round(x*pxX-1), (int) Math.round(y*pxY-1), 3, 3);

  }
}

